﻿using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;

namespace SoldiHive.Infrustructure.Extensions
{
	public static class ObjectExtensions
	{
		public static T Merge<T>(this T me, T custom)
		{
			T result = me.DeepClone<T>();
			if (custom == null)
			{
				return result;
			}

			Type t = typeof(T);

			var properties = t.GetProperties().Where(prop => prop.CanRead && prop.CanWrite);

			foreach (var prop in properties)
			{
				var value = prop.GetValue(custom, null);
				if (value != null)
					prop.SetValue(result, value, null);
			}

			return result;
		}

		public static T DeepClone<T>(this T me)
		{
			using (var memoryStream = new MemoryStream())
			{
				var formatter = new BinaryFormatter();
				formatter.Serialize(memoryStream, me);
				memoryStream.Position = 0;

				return (T)formatter.Deserialize(memoryStream);
			}
		}

		public static T GetProperyValue<T>(this object me, string propertyName)
		{
			var type = me.GetType();
			var property = type.GetProperty(propertyName);

			var propertyValue = (T)property.GetValue(me, null);

			return propertyValue;
		}
	}
}
